home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / mipsABI / examples / after / ptysetup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  5.0 KB  |  236 lines

  1. /*
  2.  * mipsABI porting examples
  3.  *
  4.  * ptysetup - demonstrate the method for setting up pseduo-ttys
  5.  *
  6.  *    open_master():    open the master side of pty
  7.  *    open_slave():    open the slave side of the pty
  8.  *
  9.  */
  10.  
  11. #ifdef _ABI_SOURCE
  12. #define STY_PTY
  13. #define HAVE_TERMIO
  14. #endif
  15.  
  16. #include <sys/types.h>
  17.  
  18. #ifdef HAVE_TERMIO
  19. #  include <termio.h>
  20. #else
  21. #  include <sgtty.h>
  22. #endif
  23.  
  24. #if defined(hpux) || (defined(sun) && defined(SVR4))
  25. #  include <sys/file.h>
  26. #endif
  27.  
  28. #ifdef SCO
  29. #  include <sys/fcntl.h>
  30. #endif
  31.  
  32. #ifdef STR_PTY
  33. #  include <sys/stropts.h>
  34. #  include <signal.h>
  35. #endif
  36.  
  37. #if defined(PTC_PTY)
  38. #  include <sys/stropts.h>
  39. #  include <sys/stat.h>
  40. #  include <sys/sysmacros.h>
  41. #elif defined(sgi)
  42. #  include <fcntl.h>
  43. #  include <signal.h>
  44. #  include <sys/stat.h>
  45. #endif
  46.  
  47. #include <stdio.h>
  48.  
  49. /* prototypes */
  50. static int open_master (void);
  51. static int open_slave (int);
  52.  
  53. #ifdef STR_PTY
  54. /* STREAMS ptys need separate read and write fd's */
  55. FILE *ex_fpin = NULL;
  56. FILE *ex_fpout = NULL;
  57. #else
  58. FILE *ex_fp = NULL;
  59. #endif
  60.  
  61. int ex_pid = 0;            /* example process id */
  62. static int ex_InputId;  /* example input id */
  63.  
  64. #if defined(PTC_PTY)
  65. static char pty[] = "/dev/ptc";         /* clone dev of pseudo-terminal */
  66. static char tty[15];                    /* slave side of pseudo-terminal */
  67. int pts_master;                         /* master filedes */
  68. char ex_tty[15];
  69. #endif
  70.  
  71. #if defined(IRIX4_PTY)
  72. char *_getpty(int*, int, mode_t, int);
  73. static char tty[15];
  74. static char pty[15];
  75. char ex_tty[15];
  76. #endif
  77.  
  78. #ifdef STR_PTY
  79. static char pty[] = "/dev/ptmx";
  80. static char tty[15];                    /* slave side of pseudo-terminal */
  81. int pts_master;                         /* master filedes */
  82. char ex_tty[15];
  83. #endif
  84.  
  85. #if !defined(STR_PTY) && !defined(PTC_PTY) && !defined(IRIX4_PTY)
  86. static char     pty[11] = "/dev/pty??";    /* master side of pseudo-terminal */
  87. static char     tty[11] = "/dev/tty??";    /* slave side of pseudo-terminal */
  88. char ex_tty[11] = "/dev/tty??";
  89. #endif
  90.  
  91. static int hold_slave = -1;
  92. extern char    *ex_prompt;
  93.  
  94. /*
  95.  * dummy main for compiling
  96.  */
  97. main ()
  98. {
  99.     open_master ();
  100. }
  101.  
  102. /*
  103.  *  This program talks to a child process through a pseudo terminal which
  104.  *  is a pair of master and slave devices: /dev/pty?? and /dev/tty??, where
  105.  *  ?? goes from p0 to sf (system dependent).  The pty is opened for both
  106.  *  read and write. Some systems use SYSV STREAMS based pty's. For these
  107.  *  define STR_PTY. Some use /dev/ptc based pty's, for those use PTC_PTY.
  108.  */
  109. static int open_master()
  110. {
  111.   int  i, master, fd;
  112.   char c;
  113.  
  114. #ifdef IRIX4_PTY
  115.   char *line;
  116.   SIG_PF oldintr;
  117. #endif
  118.   
  119. #if defined(PTC_PTY)
  120.   if ((pts_master = open(pty, O_RDWR)) >= 0)
  121.     {
  122.       struct stat sb;
  123.       
  124.       if (fstat(pts_master, &sb) < 0)
  125.     close(pts_master);
  126.       else
  127.     {
  128.       hold_slave = minor(sb.st_rdev);
  129.       return(pts_master);
  130.     }
  131.     }
  132. #endif
  133.  
  134. #ifdef IRIX4_PTY
  135.   if ((oldintr = signal(SIGCHLD, SIG_DFL)) == SIG_ERR)
  136.     {
  137.       perror("bad return from signal");
  138.       exit(1);
  139.     }
  140.   line = _getpty(&master, O_RDWR | O_NDELAY, 0600, 0);
  141.   if (signal(SIGCHLD, oldintr) == SIG_ERR)
  142.     {
  143.       perror("bad return from signal");
  144.       exit(1);
  145.     }
  146.   if(line)
  147.     {
  148.       strcpy(tty, line);
  149.       strcpy(ex_tty, line);
  150.       return(master);
  151.     }
  152. #endif
  153.  
  154. #ifdef STR_PTY
  155.   if ((pts_master = open(pty, O_RDWR)) >= 0)
  156.     {
  157.       grantpt(pts_master);
  158.       unlockpt(pts_master);
  159.       return(pts_master);
  160.     }
  161. #endif
  162.   
  163. #if !defined(STR_PTY) && !defined(PTC_PTY) && !defined(IRIX4_PTY)
  164.   for (c='p'; c<'z'; c++) 
  165.     {
  166.       for (i=0; i<16; i++) 
  167.     {
  168.       pty[8] = c;
  169.       pty[9] = "0123456789abcdef"[i];
  170.       tty[8] = c;
  171.       tty[9] = pty[9];
  172.       /*
  173.        * I need to check that tty is not the same device we are using
  174.        * for child's pseudo-terminal. Xtty has to find its own. If this
  175.        * it the first pseudo-tty then ex_tty[0] is "??" otherwise it
  176.        * keeps the last letters of child's tty.
  177.        */
  178.       if (strcmp(&ex_tty[8], &tty[8]) &&
  179.           (master = open(pty, O_RDWR)) >= 0)
  180.         {
  181.           if ((hold_slave = open(tty, O_RDWR)) >= 0)
  182.         return (master);
  183.           else close(master);
  184.         }
  185.     }
  186.     }
  187. #endif
  188.   
  189.   fprintf(stderr, "ptysetup: all ptys in use\n");
  190.   return(-1);
  191. }
  192.  
  193. static int open_slave(int pts_slave)
  194. {
  195.  
  196. #ifdef STR_PTY
  197.   char          *ptsname();
  198.   char          *slavename;
  199.  
  200.   slavename = ptsname (pts_master);    /* get name of slave */
  201.   strcpy (tty, slavename);        /* copy over to save area */
  202.   strcpy (ex_tty, slavename);
  203.   if ((pts_slave = open(tty, O_RDWR)) >= 0)
  204.     {
  205.       /*XXX todo: need to make sure these succeed */
  206.       ioctl (pts_slave, I_PUSH, "ptem");
  207.       ioctl (pts_slave, I_PUSH, "ldterm");
  208.       ioctl (pts_slave, I_PUSH, "ttcompat");
  209.       return(pts_slave);
  210.     }
  211. #endif
  212.  
  213. #if defined(PTC_PTY)
  214.   sprintf(tty, "/dev/ttyq%d", hold_slave);
  215.   if ((pts_slave = open(tty, O_RDWR)) >= 0) {
  216.     strcpy(ex_tty, tty);
  217.     return(pts_slave);
  218.   }
  219. #endif
  220.  
  221. #ifdef IRIX4_PTY
  222.   if ((pts_slave = open(tty, O_RDWR)) >= 0) {
  223.     strcpy(ex_tty, tty);
  224.     return(pts_slave);
  225.   }
  226. #endif
  227.  
  228. #if !defined(STR_PTY) && !defined(PTC_PTY) && !defined(IRIX4_PTY)
  229.   return(hold_slave);
  230. #else
  231.   fprintf(stderr, "ptysetup: failed to open slave pty\n");
  232.   return(-1);
  233. #endif
  234.  
  235. }
  236.